﻿using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using Newtonsoft.Json;
using YuYuKiCms.Bl.Interface;
using YuYuKiCms.Dal.Interface;
using YuYuKiCms.Dal.Model;
using YuYuKiCms.Framework.Aspect;
using YuYuKiCms.Model;

namespace YuYuKiCms.Bl.Core
{
    internal class PageBL : IPageBL
    {
        private readonly IPageRepository _pageRepository;

        public PageBL(IPageRepository pageRepository)
        {
            _pageRepository = pageRepository;
        }

        public PageVm GetById(int id)
        {
            return Mapper.Map<PageVm>(_pageRepository.GetId(id));
        }

        [ThrowArgumentNullExceptionAspect(AttributeExclude = true)]
        public IEnumerable<PageVm> GetChildren(int? parentId)
        {
            return Mapper.Map<List<PageVm>>(_pageRepository.GetChildren(parentId).ToList());
        }

        public int AddPage(PageVm page)
        {
            var pageMenu = Mapper.Map<PageMenu>(page);
            _pageRepository.InsertOrUpdate(pageMenu, pageMenu.Id);
            return pageMenu.Id;
        }

        public void DeletePage(int pageId)
        {
            _pageRepository.Delete(pageId);
        }

        public void SaveMenu(string menuJsonString)
        {
            var rank = 1;

            var menuJsons = JsonConvert.DeserializeObject<List<MenuJsonVm>>(menuJsonString);
            var pages = MenuJsonToPageMenu(menuJsons);

            foreach (var menu in pages)
            {
                var page = _pageRepository.GetId(menu.Id);
                page.IdParent = menu.IdParent;
                page.Rank = menu.Rank;
            }

            _pageRepository.SaveChange();
        }

        public void UpdatePage(PageVm page)
        {
            if (page.Id == null)
                return;
            var pageFromDB = _pageRepository.GetId(page.Id.Value);
            Mapper.Map(page, pageFromDB);
        }

        public List<PageVm> GetAll()
        {
            return Mapper.Map<List<PageVm>>(_pageRepository.GetAll(f => f.IdParent.HasValue));
        }

        internal List<PageMenu> MenuJsonToPageMenu(List<MenuJsonVm> menuJsonVms, List<PageMenu> pageMenus = null)
        {
            pageMenus = pageMenus ?? new List<PageMenu>();
            int? idParent = null;
            if (pageMenus.Any())
            {
                idParent = pageMenus.Last().Id;
            }

            foreach (var menuJsonVm in menuJsonVms)
            {
                pageMenus.Add(new PageMenu
                {
                    Id = menuJsonVm.Id,
                    IdParent = idParent,
                    Rank = pageMenus.Count()
                });

                if (menuJsonVm.Children != null && menuJsonVm.Children.Any())
                {
                    MenuJsonToPageMenu(menuJsonVm.Children, pageMenus);
                }
            }

            return pageMenus;
        }
    }
}